namespace TXLooker.WorkItemExtention.WIQL
{
    using System;
    using System.Globalization;

    public class NodeSelect : NodeList
    {
        public NodeSelect() : base(NodeType.Select, 6)
        {
        }

        public override void Bind(IExternal e, NodeTableName tableContext, NodeFieldName fieldContext)
        {
            Tools.EnsureSyntax(this.From != null, SyntaxError.FromIsNotSpecified, null);
            this.From.Bind(e, null, null);
            Tools.EnsureSyntax(this.From.NodeType == NodeType.TableName, SyntaxError.ExpectingTableName, this.From);
            if (this.Fields != null)
            {
                this.Fields.Bind(e, this.From, null);
                Tools.EnsureSyntax(this.Fields.NodeType == NodeType.FieldList, SyntaxError.ExpectingFieldList, this.Fields);
            }
            if (this.GroupBy != null)
            {
                this.GroupBy.Bind(e, this.From, null);
                Tools.EnsureSyntax(this.GroupBy.NodeType == NodeType.GroupFieldList, SyntaxError.ExpectingFieldList, this.GroupBy);
            }
            if (this.OrderBy != null)
            {
                this.OrderBy.Bind(e, this.From, null);
                Tools.EnsureSyntax(this.OrderBy.NodeType == NodeType.OrderFieldList, SyntaxError.ExpectingFieldList, this.OrderBy);
            }
            if (this.Where != null)
            {
                this.Where.Bind(e, this.From, null);
                Tools.EnsureSyntax(this.Where.DataType == DataType.Bool, SyntaxError.ExpectingCondition, this.Where);
            }
            if (this.AsOf != null)
            {
                this.AsOf.Bind(e, this.From, null);
                if (e != null)
                {
                    Tools.EnsureSyntax(this.AsOf.IsScalar && this.AsOf.CanCastTo(DataType.Date, e.CultureInfo), SyntaxError.ExpectingDate, this.AsOf);
                }
            }
            base.Bind(e, tableContext, fieldContext);
        }

        public override Node Optimize(IExternal e, NodeTableName tableContext, NodeFieldName fieldContext)
        {
            if (this.Where != null)
            {
                this.Where = this.Where.Optimize(e, this.From, null);
            }
            if (this.AsOf != null)
            {
                this.AsOf = this.AsOf.Optimize(e, null, null);
            }
            return base.Optimize(e, tableContext, fieldContext);
        }

        public override string ToString()
        {
            string text = "select ";
            string[] textArray = new string[] { "{0}", " from {0}", " where {0}", "group by {0}", " order by {0}", " asof {0}" };
            for (int i = 0; i < textArray.Length; i++)
            {
                Node node = this[i];
                if (node != null)
                {
                    string text2 = node.ToString();
                    if (!string.IsNullOrEmpty(text2))
                    {
                        text = text + string.Format(CultureInfo.InvariantCulture, textArray[i], new object[] { text2 });
                    }
                }
            }
            return text;
        }

        public Node AsOf
        {
            get
            {
                return this[5];
            }
            set
            {
                this[5] = value;
            }
        }

        public override DataType DataType
        {
            get
            {
                return DataType.Void;
            }
        }

        public NodeFieldList Fields
        {
            get
            {
                return (NodeFieldList) this[0];
            }
            set
            {
                this[0] = value;
            }
        }

        public NodeTableName From
        {
            get
            {
                return (NodeTableName) this[1];
            }
            set
            {
                this[1] = value;
            }
        }

        public NodeFieldList GroupBy
        {
            get
            {
                return (NodeFieldList) this[3];
            }
            set
            {
                this[3] = value;
            }
        }

        public NodeFieldList OrderBy
        {
            get
            {
                return (NodeFieldList) this[4];
            }
            set
            {
                this[4] = value;
            }
        }

        public override Priority Priority
        {
            get
            {
                return Priority.SelectOperator;
            }
        }

        public Node Where
        {
            get
            {
                return this[2];
            }
            set
            {
                this[2] = value;
            }
        }
    }
}

